package com.zsk.shop.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zsk.shop.common.base.BaseResponse;
import com.zsk.shop.common.base.BizException;
import com.zsk.shop.common.base.NoMsgException;
import com.zsk.shop.common.base.page.BaseDateQueryParams;
import com.zsk.shop.common.base.page.BasePageFactory;
import com.zsk.shop.common.constant.Constant;
import com.zsk.shop.common.utils.*;
import com.zsk.shop.entity.*;
import com.zsk.shop.enums.EnumRatioWithLv;
import com.zsk.shop.enums.EnumUserAccountChangeType;
import com.zsk.shop.enums.EnumWithdrawStatus;
import com.zsk.shop.enums.EnumWithdrawType;
import com.zsk.shop.mapper.ShopUserAccountMapper;
import com.zsk.shop.model.params.GopAddUserAccountParams;
import com.zsk.shop.model.params.GopFinanceAddUserAccountParams;
import com.zsk.shop.model.params.GopShopUserAccountListParams;
import com.zsk.shop.model.params.MoneyAccountInsertParams;
import com.zsk.shop.model.results.ShopUserAccountListResult;
import com.zsk.shop.model.results.ShopUserAccountResult;
import com.zsk.shop.model.results.WithdrawMethodResult;
import org.apache.commons.collections.map.HashedMap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author ljh
 * @create 2021/5/14 14:18
 */
@Service
public class UserAccountService extends ServiceImpl<ShopUserAccountMapper, ShopUserAccount> {

    private final static Logger logger = LoggerFactory.getLogger(UserAccountService.class);

    @Resource
    private ShopUserService userService;
    @Resource
    private WithdrawApplyService withdrawApplyService;
    @Resource
    private ShopOrderService orderService;
    @Resource
    private AliPayAccountUserService aliPayAccountUserService;
    @Resource
    private BankCardService bankCardService;
    @Resource
    private BankUtils bankUtils;
    @Resource
    private DataDictionaryService dataDictionaryService;

    /**
     * 获取用户最新一条数据的账户流水内容
     *
     * @param userNo
     * @return
     */
    public ShopUserAccount getUserAccountByUserNo(String userNo) {
        LambdaQueryWrapper<ShopUserAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopUserAccount::getUserNo, userNo);
        queryWrapper.orderByDesc(ShopUserAccount::getId);
        queryWrapper.last("limit 1");
        ShopUserAccount shopUserAccount = this.getOne(queryWrapper);
        //如果是空则初始化账户
        if (ToolUtil.isEmpty(shopUserAccount)) {
            shopUserAccount = ShopUserAccount.builder().userNo(userNo)
                    .lastBalance(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .changeBalance(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .changeFrozen(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .totalFrozen(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .nowBalance(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .content(EnumUserAccountChangeType.INIT.getContent())
                    .accountChangeType(EnumUserAccountChangeType.INIT.getCode())
                    .createTime(new Date()).build();
            this.save(shopUserAccount);
        }
        return shopUserAccount;
    }

    /**
     * 初始化账户 INIT
     *
     * @param userNos
     * @return
     */
    public void initUserAccount(List<String> userNos) {
        LambdaQueryWrapper<ShopUserAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(ShopUserAccount::getUserNo, userNos);
        List<ShopUserAccount> shopUserAccountList = list(queryWrapper);
        //已有账户的
        List<String> haveAccountUserNos = shopUserAccountList.stream().map(ShopUserAccount::getUserNo).collect(Collectors.toList());
        userNos.removeAll(haveAccountUserNos);
        List<ShopUserAccount> shopUserAccounts = new ArrayList<>();
        //如果是空则初始化账户
        for (String userNo : userNos) {
            ShopUserAccount shopUserAccount = ShopUserAccount.builder().userNo(userNo)
                    .lastBalance(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .changeBalance(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .changeFrozen(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .totalFrozen(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .nowBalance(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                    .content(EnumUserAccountChangeType.INIT.getContent())
                    .accountChangeType(EnumUserAccountChangeType.INIT.getCode())
                    .createTime(new Date()).build();
            shopUserAccounts.add(shopUserAccount);
        }
        if (ToolUtil.isNotEmpty(shopUserAccounts)) {
            this.saveOrUpdateBatch(shopUserAccounts);
        }
        return;
    }

    public BigDecimal getUserMoneyAccountNowBalance(String userNo) {
        ShopUserAccount userAccount = getUserAccountByUserNo(userNo);
        //可提现余额
        BigDecimal canWithdrawBalance = userAccount.getNowBalance().subtract(userAccount.getTotalFrozen()).setScale(2, BigDecimal.ROUND_HALF_UP);
        //入账冻结余额-从其余入账表中查询数据后绑定[正常到账后该值插入流水，后不显示入账]
        BigDecimal entryWaitFrozenBalance = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP);
        BigDecimal balance = canWithdrawBalance.add(entryWaitFrozenBalance).setScale(2, BigDecimal.ROUND_HALF_UP);
        return balance;
    }

    public String changeContent(String content, BigDecimal money) {
        if (content.contains(EnumUserAccountChangeType.WITHDRAWAL.getContent()) ||
                content.contains(EnumUserAccountChangeType.WITHDRAWAL_SUCCESS.getContent()) ||
                content.contains(EnumUserAccountChangeType.WITHDRAWAL_FAIL.getContent())) {
            content = content.replaceAll("s%", money.setScale(2, BigDecimal.ROUND_HALF_UP).toString());
        }
        return content;
    }

    /**
     * 个人账户余额
     *
     * @return
     */
    public BaseResponse<ShopUserAccountResult> getMoneyAccount() {
        String userNo = HttpContext.getUserNo();
        if (ToolUtil.isNotEmpty(userNo)) {
            ShopUser user = userService.queryByUserNo(userNo);
            //个人账户余额
            ShopUserAccount userAccount = this.getUserAccountByUserNo(userNo);
            //实名
            Boolean idCardHave = ToolUtil.isNotEmpty(user.getIdentityCard()) ? true : false;
            Boolean trueNameHave = ToolUtil.isNotEmpty(user.getTrueName()) ? true : false;
            Integer idCardInfo = (idCardHave && trueNameHave) ? 2 : ((trueNameHave && !idCardHave) ? 1 : 0);
            //可提现余额
            BigDecimal canWithdrawBalance = userAccount.getNowBalance().subtract(userAccount.getTotalFrozen()).setScale(2, BigDecimal.ROUND_HALF_UP);
            //入账冻结余额-从其余入账表中查询数据后绑定[正常到账后该值插入流水，后不显示入账]
            BigDecimal entryWaitFrozenBalance = BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP);
            BigDecimal balance = canWithdrawBalance.add(entryWaitFrozenBalance).setScale(2, BigDecimal.ROUND_HALF_UP);
            //微信
            Boolean haveWeChatAccount = ToolUtil.isNotEmpty(user.getWxUnionId()) ? true : false;
            AliPayAccountUser aliPayAccountUser = aliPayAccountUserService.getByUser(userNo);
            String aliPayAccount = ToolUtil.isNotEmpty(aliPayAccountUser) ? aliPayAccountUser.getAlipayAccount() : "";
            List<BankCardUser> bankCardUserList = bankCardService.getBankCardInfo(userNo);
            //添加数据
            ShopUserAccountResult result = ShopUserAccountResult.builder().nowBalance(userAccount.getNowBalance().toString())
                    .totalFrozen(userAccount.getTotalFrozen().toString()).entryWaitFrozen(entryWaitFrozenBalance.toString())
                    .canWithdrawBalance(canWithdrawBalance.toString())
                    .haveWeChatBind(haveWeChatAccount).balance(balance.toString()).aliPayAccount(aliPayAccount).bankCardInfo(bankCardUserList)
                    .idCardInfo(idCardInfo).trueName(ToolUtil.isNotEmpty(user.getTrueName()) ? user.getTrueName() : "未实名").build();
            return BaseResponse.success(result);
        }
        return BaseResponse.error("当前账号信息查询失败");
    }

    /**
     * 提现->冻结流水
     *
     * @param money
     * @param userNo
     * @param withdrawId
     */
    public void withdraw(BigDecimal money, String userNo, Long withdrawId) {
        ShopUserAccount moneyAccountUser = getUserAccountByUserNo(userNo);
        String content = changeContent(EnumUserAccountChangeType.WITHDRAWAL.getContent(), money);
        ShopUserAccount newInfo = ShopUserAccount.builder().userNo(userNo).lastBalance(moneyAccountUser.getNowBalance())
                .changeBalance(money.multiply(BigDecimal.valueOf(-1)).setScale(2, BigDecimal.ROUND_HALF_UP)).changeFrozen(money)
                .totalFrozen(moneyAccountUser.getTotalFrozen().add(money).setScale(2, BigDecimal.ROUND_HALF_UP))
                .nowBalance(moneyAccountUser.getNowBalance()).content(content)
                .accountChangeType(EnumUserAccountChangeType.WITHDRAWAL.getCode())
                .createTime(new Date()).withdrawId(withdrawId).build();
        this.save(newInfo);
    }

    /**
     * 提现成功
     *
     * @param shopWithdrawApply
     */
    public void withdrawSuccess(ShopWithdrawApply shopWithdrawApply) {
        String userNo = shopWithdrawApply.getUserNo();
        BigDecimal money = shopWithdrawApply.getWithdrawMoney();
        ShopUserAccount moneyAccountUser = getUserAccountByUserNo(userNo);
        String content = changeContent(EnumUserAccountChangeType.WITHDRAWAL_SUCCESS.getContent(), money);
        ShopUserAccount newInfo = ShopUserAccount.builder().userNo(userNo).lastBalance(moneyAccountUser.getNowBalance())
                .changeBalance(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                .changeFrozen(money.multiply(BigDecimal.valueOf(-1)).setScale(2, BigDecimal.ROUND_HALF_UP))
                .totalFrozen(moneyAccountUser.getTotalFrozen().subtract(money).setScale(2, BigDecimal.ROUND_HALF_UP))
                .nowBalance(moneyAccountUser.getNowBalance().subtract(money).setScale(2, BigDecimal.ROUND_HALF_UP))
                .content(content).accountChangeType(EnumUserAccountChangeType.WITHDRAWAL_SUCCESS.getCode())
                .createTime(new Date()).build();
        this.save(newInfo);
        //todo第三方消息短信或者推送
    }

    /**
     * 提现失败
     *
     * @param shopWithdrawApply
     */
    public void withdrawFail(ShopWithdrawApply shopWithdrawApply) {
        String userNo = shopWithdrawApply.getUserNo();
        BigDecimal money = shopWithdrawApply.getWithdrawMoney();
        ShopUserAccount moneyAccountUser = getUserAccountByUserNo(userNo);
        String content = changeContent(EnumUserAccountChangeType.WITHDRAWAL_FAIL.getContent(), money);
        ShopUserAccount newInfo = ShopUserAccount.builder().userNo(userNo).lastBalance(moneyAccountUser.getNowBalance())
                .changeBalance(money)//BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                .changeFrozen(money.multiply(BigDecimal.valueOf(-1)).setScale(2, BigDecimal.ROUND_HALF_UP))
                .totalFrozen(moneyAccountUser.getTotalFrozen().subtract(money).setScale(2, BigDecimal.ROUND_HALF_UP))
                .nowBalance(moneyAccountUser.getNowBalance())
                .content(content).accountChangeType(EnumUserAccountChangeType.WITHDRAWAL_FAIL.getCode())
                .createTime(new Date()).build();
        this.save(newInfo);
        //todo第三方消息短信或者推送
    }

    /**
     * 用户账户流水插入（获取现金）
     *
     * @param params
     * @throws BizException
     */
    public void moneyAccountInsert(MoneyAccountInsertParams params) throws NoMsgException {
        String userNo = params.getUserNo();
        String money = params.getMoney();
        Integer type = params.getChangeType();
        String orderNo = params.getOrderNo();
        if (type.equals(EnumUserAccountChangeType.FINANCE_ADD.getCode()) ||
                type.equals(EnumUserAccountChangeType.FINANCE_ADD_REMARK.getCode()) ||
                type.equals(EnumUserAccountChangeType.FINANCE_REPAIR_REMARK.getCode()) ||
                type.equals(EnumUserAccountChangeType.FINANCE_ADD_REMARK_COMMISSION.getCode())) {
            String pwd = dataDictionaryService.getValueStrByKey(Constant.FINANCE_PWD_KEY);
            if (ToolUtil.isEmpty(params.getFinancePassword()) ||
                    !params.getFinancePassword().equals(ToolUtil.isEmpty(pwd) ? "buDqfb12D47bf5v78ao" : pwd)) {
                throw new NoMsgException("校验财务打款密码失败");
            }
        }
//       else if (type.equals(EnumUserAccountChangeType.PURCHASING_SUBSIDY.getCode())) {
//            if (ToolUtil.isEmpty(params.getOrderNo())) {
//                throw new BizException("订单编号有误");
//            }
//            orderNo = params.getOrderNo();
//            groupNo = params.getGroupNo();
//            WmOrder order = orderService.queryOne(orderNo);
////            //查询出订单
//        }  else if (type.equals(EnumUserAccountChangeType.OTHER.getCode())) {
//            //其他
//        }
        BigDecimal changeMoney = new BigDecimal(money).setScale(2, BigDecimal.ROUND_HALF_UP);
        String content = "";
        if (type.equals(EnumUserAccountChangeType.FINANCE_ADD_REMARK.getCode())) {
            content = params.getRemark();
        } else if (type.equals(EnumUserAccountChangeType.FINANCE_REPAIR_REMARK.getCode())) {
            changeMoney = changeMoney.multiply(new BigDecimal("-1")).setScale(2, BigDecimal.ROUND_HALF_UP);
            content = params.getRemark();
        } else if (type.equals(EnumUserAccountChangeType.FINANCE_ADD_REMARK_COMMISSION.getCode())) {
            content = "提成";
        } else {
            content = EnumUserAccountChangeType.getContentByCode(type);
            content = changeContent(content, changeMoney);
        }
        ShopUserAccount lastMoneyAccount = getUserAccountByUserNo(userNo);
        ShopUserAccount moneyAccount = ShopUserAccount.builder().userNo(userNo)
                .lastBalance(lastMoneyAccount.getNowBalance()).changeBalance(changeMoney)
                .changeFrozen(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                .totalFrozen(lastMoneyAccount.getTotalFrozen())
                .nowBalance(lastMoneyAccount.getNowBalance().add(changeMoney).setScale(2, BigDecimal.ROUND_HALF_UP))
                .content(content).accountChangeType(type).createTime(new Date()).orderNo(orderNo)
                .tip(ToolUtil.isNotEmpty(params.getHaveCommission()) ? params.getHaveCommission() : false).build();
        this.save(moneyAccount);
    }

    /**
     * 用户账户流水插入（获取现金）
     *
     * @param params
     * @throws BizException
     */
    public void userAccountRepair(MoneyAccountInsertParams params) throws BizException {
        String userNo = params.getUserNo();
        String money = params.getMoney();
        Integer type = params.getChangeType();
        String orderNo = params.getOrderNo();
        //变动金额
        BigDecimal changeMoney = new BigDecimal(money).setScale(2, BigDecimal.ROUND_HALF_UP);
        String content = EnumUserAccountChangeType.getContentByCode(type);
        ShopUserAccount lastMoneyAccount = getUserAccountByUserNo(userNo);
        BigDecimal lastBalance = lastMoneyAccount.getNowBalance();
        ShopUserAccount moneyAccount = ShopUserAccount.builder().userNo(userNo)
                .lastBalance(lastBalance).changeBalance(changeMoney)
                .changeFrozen(BigDecimal.ZERO.setScale(2, BigDecimal.ROUND_HALF_UP))
                .totalFrozen(lastMoneyAccount.getTotalFrozen())
                .nowBalance(lastMoneyAccount.getNowBalance().add(changeMoney).setScale(2, BigDecimal.ROUND_HALF_UP))
                .content(content).accountChangeType(type).createTime(new Date())
                .orderNo(orderNo).build();
        this.save(moneyAccount);
    }

    public BaseResponse<ShopUserAccountListResult> userAccountList(BaseDateQueryParams params) {
        Page pageContext = BasePageFactory.defaultPage(params.getPage(), params.getLimit());
        LambdaQueryWrapper<ShopUserAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopUserAccount::getUserNo, HttpContext.getUserNo());
        queryWrapper.and(x -> x.ne(ShopUserAccount::getAccountChangeType, EnumUserAccountChangeType.INIT.getCode())
                .ne(ShopUserAccount::getAccountChangeType, EnumUserAccountChangeType.FINANCE_ADD_REMARK_COMMISSION.getCode())
                .ne(ShopUserAccount::getAccountChangeType, EnumUserAccountChangeType.WITHDRAWAL_SUCCESS.getCode())
                .ne(ShopUserAccount::getAccountChangeType, EnumUserAccountChangeType.WITHDRAWAL_FAIL.getCode()));
        if (!ToolUtil.isAllEmpty(params.getStartTime(), params.getEndTime())) {
            queryWrapper.and(x -> x.ge(ShopUserAccount::getCreateTime, DateUtils.parse2Date(params.getStartTime(), DateUtils.YYYYMMDDHHMMSS))
                    .le(ShopUserAccount::getCreateTime, DateUtils.parse2Date(params.getEndTime(), DateUtils.YYYYMMDDHHMMSS)));
        }
        queryWrapper.orderByDesc(ShopUserAccount::getCreateTime, ShopUserAccount::getId);
        IPage page = this.page(pageContext, queryWrapper);
        List<ShopUserAccount> shopUserAccountList = page.getRecords();
        List<ShopUserAccountListResult> results = EntityConvertUtils.convertAListToBList(shopUserAccountList, ShopUserAccountListResult.class);
        for (ShopUserAccountListResult result : results) {
            BigDecimal changeBalance = result.getChangeBalance();
            if (changeBalance.compareTo(BigDecimal.ZERO) < 0) {
                result.setIsPositiveNumber(false);
            }
            result.setChangeBalance(changeBalance.abs().setScale(2, BigDecimal.ROUND_HALF_UP));
            Long withdrawId = result.getWithdrawId();
            if (ToolUtil.isNotEmpty(withdrawId)) {
                ShopWithdrawApply withdrawApply = withdrawApplyService.getById(withdrawId);
                Integer withdrawStatus = withdrawApply.getStatus();
                result.setWithdrawStatus(withdrawStatus);
                result.setWithdrawStatusStr(EnumWithdrawStatus.getNameByCode(withdrawStatus));
                result.setReviewReason(withdrawApply.getReviewReason());
            }
            result.setCreateTimeStr(DateUtils.format(result.getCreateTime(), DateUtils.YYYYMMDDHHMM));
        }
        page.setRecords(results);
        return BasePageFactory.createPageInfo(page);
    }

    /**
     * 获取用户账号提现方式
     *
     * @return
     */
    public BaseResponse<WithdrawMethodResult> getWithdrawMethod() {
        List<WithdrawMethodResult> list = new ArrayList<>();
        String userNo = HttpContext.getUserNo();
        ShopUser user = userService.queryByUserNo(userNo);
        String name = user.getTrueName();
        if (ToolUtil.isEmpty(name)) {
            return BaseResponse.error("该账号暂未实名认证不支持提现。");
        }
        //微信
        WithdrawMethodResult r1 = null;
        if (!ToolUtil.isOneEmpty(user, user.getWxUnionId())) {
            r1 = new WithdrawMethodResult();
            r1.setId(0L);
            r1.setName("微信");
            r1.setIcon("https://oss.zhishangkeapp.com/img/signup_icon_wechat.png");
            r1.setAccountName("微信");
            r1.setApplyType(EnumWithdrawType.WECHAT.getCode());
        }
        //支付宝
        WithdrawMethodResult r2 = null;
        AliPayAccountUser alipayAccountUser = aliPayAccountUserService.getByUser(userNo);
        if (ToolUtil.isNotEmpty(alipayAccountUser)) {
            r2 = new WithdrawMethodResult();
            r2.setId(alipayAccountUser.getId());
            r2.setName("支付宝");
            r2.setIcon("https://oss.zhishangkeapp.com/img/list_icon_alipay.png");
            r2.setAccountName(alipayAccountUser.getAlipayAccount());
            r2.setApplyType(EnumWithdrawType.ALIPAY.getCode());
            r2.setCreateTime(alipayAccountUser.getCreateTime());
        }
        //银行号
        List<WithdrawMethodResult> r3s = new ArrayList<>();
        List<BankCardUser> bankCardUserList = bankCardService.getBankCardInfo(userNo);
        for (BankCardUser bankCardUser : bankCardUserList) {
            WithdrawMethodResult r = new WithdrawMethodResult();
            r.setId(bankCardUser.getId());
            r.setName(bankCardUser.getBankName());
            r.setIcon(bankCardUser.getBankIcon());
            r.setAccountName(bankCardUser.getBankCardId());
            r.setApplyType(EnumWithdrawType.CARD.getCode());
            r.setCreateTime(bankCardUser.getCreateTime());
            r3s.add(r);
        }
        //todo 提现方式插入，目前只可用支付宝/银行卡
        if (ToolUtil.isNotEmpty(r1)) {
//            list.add(r1);
        }
        if (ToolUtil.isNotEmpty(r2)) {
            list.add(r2);
        }
        if (ToolUtil.isNotEmpty(r3s)) {
            list.addAll(r3s);
        }
        list.sort((t1, t2) -> t2.getCreateTime().compareTo(t1.getCreateTime()));
        return BaseResponse.success(list);
    }

    private static final String alipay = "alipay";
    private static final String weChat = "weChat";
    private static final String bankCard = "bankCard";

    public Map<String, Boolean> getMethod() {
        Map<String, Boolean> result = new HashedMap();
        result.put(alipay, false);
        result.put(weChat, false);
        result.put(bankCard, true);
        return result;
    }

    public BaseResponse financeAddUserAccount(GopFinanceAddUserAccountParams params) {
        ShopUser user = userService.queryTrueUserByPhone(params.getPhone());
        if (ToolUtil.isEmpty(user)) {
            return BaseResponse.error("该手机号用户不存在，增加余额失败。");
        }
        String userNo = user.getUserNo();
        String orderNo = "";
        MoneyAccountInsertParams moneyAccountInsertParams = MoneyAccountInsertParams.builder()
                .userNo(userNo).changeType(EnumUserAccountChangeType.FINANCE_ADD.getCode()).money(params.getMoney())
                .orderNo(orderNo).financePassword(params.getFinancePassword()).remark(params.getRemark()).build();
        moneyAccountInsert(moneyAccountInsertParams);
        return BaseResponse.success("增加用户余额成功。");
    }

    public BaseResponse addUserAccount(GopAddUserAccountParams params) {
        BigDecimal money = BigDecimal.ZERO;
        try {
            money = new BigDecimal(params.getMoney()).setScale(2, BigDecimal.ROUND_DOWN);
        } catch (Exception e) {
            throw new NoMsgException("请输入正确的金额");
        }
        String userNo = params.getUserNo();
        ShopUser user = userService.queryByUserNo(userNo);
        String orderNo = "";
        Integer changeType;
        if (params.getType().equals("1")) {
            changeType = EnumUserAccountChangeType.FINANCE_ADD_REMARK.getCode();
            if (ToolUtil.isEmpty(user)) {
                return BaseResponse.error("该用户不存在，增加余额失败。");
            } else {
                if (params.getHaveCommission() && ToolUtil.isNotEmpty(user.getParentUserNo())) {
                    //上级也分佣
                    ShopUser parentUser = userService.queryByUserNo(user.getParentUserNo());
                    if (ToolUtil.isNotEmpty(parentUser) && parentUser.getVipLevel() > 0 && parentUser.getLv().equals(user.getLv())) {
                        BigDecimal parentMoney = money.multiply(EnumRatioWithLv.getRecommendRatioByLv(parentUser.getLv()));
                        MoneyAccountInsertParams parentMoneyAccountInsertParams = MoneyAccountInsertParams.builder()
                                .userNo(parentUser.getUserNo())
                                .changeType(EnumUserAccountChangeType.FINANCE_ADD_REMARK_COMMISSION.getCode())
                                .money(parentMoney.setScale(2, BigDecimal.ROUND_DOWN).toString())
                                .orderNo(orderNo).financePassword(params.getFinancePassword()).remark(params.getRemark())
                                .haveCommission(params.getHaveCommission()).build();
                        moneyAccountInsert(parentMoneyAccountInsertParams);
                    }
                }
            }
        } else if (params.getType().equals("2")) {
            changeType = EnumUserAccountChangeType.FINANCE_REPAIR_REMARK.getCode();
        } else {
            return BaseResponse.error("当前操作方式不正确");
        }
        //本人名下打钱
        MoneyAccountInsertParams moneyAccountInsertParams = MoneyAccountInsertParams.builder()
                .userNo(userNo).changeType(changeType).money(params.getMoney())
                .orderNo(orderNo).financePassword(params.getFinancePassword()).remark(params.getRemark())
                .haveCommission(params.getHaveCommission()).build();
        moneyAccountInsert(moneyAccountInsertParams);
        return BaseResponse.success("操作用户余额成功。");
    }

    public BaseResponse<ShopUserAccountListResult> gopShopUserAccountList(GopShopUserAccountListParams params) {
        Page pageContext = BasePageFactory.defaultPage(params.getPage(), params.getLimit());
        LambdaQueryWrapper<ShopUserAccount> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ShopUserAccount::getUserNo, params.getUserNo());
        if (params.getJustFinance()) {
            queryWrapper.and(x -> x.eq(ShopUserAccount::getAccountChangeType, EnumUserAccountChangeType.FINANCE_ADD_REMARK.getCode())
                    .or().eq(ShopUserAccount::getAccountChangeType, EnumUserAccountChangeType.FINANCE_REPAIR_REMARK.getCode()));
        }
        if (!ToolUtil.isAllEmpty(params.getStartTime(), params.getEndTime())) {
            queryWrapper.and(x -> x.ge(ShopUserAccount::getCreateTime, DateUtils.parse2Date(params.getStartTime(), DateUtils.YYYYMMDD))
                    .le(ShopUserAccount::getCreateTime, DateUtils.parse2Date(params.getEndTime(), DateUtils.YYYYMMDD)));
        }
//        queryWrapper.and(x -> x.ne(ShopUserAccount::getAccountChangeType, EnumUserAccountChangeType.WITHDRAWAL_SUCCESS.getCode())
//                .ne(ShopUserAccount::getAccountChangeType, EnumUserAccountChangeType.WITHDRAWAL_FAIL.getCode()));
        queryWrapper.orderByDesc(ShopUserAccount::getCreateTime, ShopUserAccount::getId);
        IPage page = this.page(pageContext, queryWrapper);
        List<ShopUserAccount> shopUserAccountList = page.getRecords();
        List<ShopUserAccountListResult> results = EntityConvertUtils.convertAListToBList(shopUserAccountList, ShopUserAccountListResult.class);
        for (ShopUserAccountListResult result : results) {
            BigDecimal changeBalance = result.getChangeBalance();
            if (changeBalance.compareTo(BigDecimal.ZERO) < 0) {
                result.setIsPositiveNumber(false);
            }
            result.setChangeBalance(changeBalance.abs().setScale(2, BigDecimal.ROUND_HALF_UP));
            Long withdrawId = result.getWithdrawId();
            if (ToolUtil.isNotEmpty(withdrawId)) {
                ShopWithdrawApply withdrawApply = withdrawApplyService.getById(withdrawId);
                Integer withdrawStatus = withdrawApply.getStatus();
                result.setWithdrawStatus(withdrawStatus);
                result.setWithdrawStatusStr(EnumWithdrawStatus.getNameByCode(withdrawStatus));
                result.setReviewReason(withdrawApply.getReviewReason());
            }
            result.setCreateTimeStr(DateUtils.format(result.getCreateTime(), DateUtils.YYYYMMDDHHMM));
        }
        page.setRecords(results);
        return BasePageFactory.createPageInfo(page);
    }
}
